package com.swak.rpc.config.model;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.stream.Stream;

import com.swak.rpc.Constants;
import com.swak.utils.ReflectUtils;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Getter
@Setter
@Accessors(chain = true)
public class MethodDescriptor {

	private final Method method;
    private final String paramDesc;
    private final String[] compatibleParamSignatures;
    private final Class<?>[] parameterClasses;
    private final Class<?> returnClass;
    private final Type[] returnTypes;
    private final String methodName;
    private final boolean generic;

    public MethodDescriptor(Method method) {
        this.method = method;
        this.parameterClasses = method.getParameterTypes();
        this.returnClass = method.getReturnType();
        this.returnTypes = ReflectUtils.getReturnTypes(method);
        this.paramDesc = ReflectUtils.getDesc(parameterClasses);
        this.compatibleParamSignatures = Stream.of(parameterClasses)
                .map(Class::getName)
                .toArray(String[]::new);
        this.methodName = method.getName();
        this.generic = (methodName.equals(Constants.$INVOKE) || methodName.equals(Constants.$INVOKE_ASYNC)) && parameterClasses.length == 3;
    }
}
